package org.skatiger.jrove.resource;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;

import org.skatiger.jrove.util.AssertUtil;

public class ResourceAnnotationHelper {
    private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory
            .getLogger(ResourceAnnotationHelper.class);
    private static Map<Class<?>, List<Resource>> CACHE = new WeakHashMap<Class<?>, List<Resource>>();

    public static List<Resource> getResourceDependences(Class<?> resourceClass) {
        AssertUtil.notNull(resourceClass);
        if (!CACHE.containsKey(resourceClass)) {
            List<Resource> resources = findResourcesByAnnotation(resourceClass);
            CACHE.put(resourceClass, resources);
        }
        List<Resource> resources = Collections.unmodifiableList(CACHE
                .get(resourceClass));
        return resources;
    }

    //    public static List<Resource> getResourceDependences(
    //            UIComponent resourceComponent) {
    //        Assert.notNull(resourceComponent);
    //        List<Resource >
    //    }

    private static List<Resource> findResourcesByAnnotation(Class<?> clazz) {
        List<Resource> resources = new ArrayList<Resource>();
        {//process ResourceDependence
            ResourceDependence rd = clazz
                    .getAnnotation(ResourceDependence.class);
            if (rd != null) {
                ComponentResource resource = new ComponentResource(rd);
                resources.add(resource);
                if (logger.isDebugEnabled()) {
                    logger.debug("found ResourceDependence annotation with type "
                            + clazz.getName());
                }
            }
        }
        {//process ResourceDependences
            ResourceDependences dependences = clazz
                    .getAnnotation(ResourceDependences.class);
            if (dependences != null) {
                ResourceDependence[] _rds = dependences.value();
                for (ResourceDependence rd : _rds) {
                    ComponentResource resource = new ComponentResource(rd);
                    resources.add(resource);
                }
                if (logger.isDebugEnabled()) {
                    logger.debug("found ResourceDependences[@length="
                            + _rds.length + "] annotation with type "
                            + clazz.getName());
                }
            }
        }

        return resources;
    }

    static class ComponentResource implements Resource {
        private ResourceType type;
        private String value;

        public ComponentResource(final ResourceDependence resourceDependence) {
            this.value = resourceDependence.value();
            this.type = resourceDependence.type();
        }

        public ResourceType getType() {
            return type;
        }

        public String getValue() {
            return value;
        }

    }
}
